package com.example.pool;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * 线程池的概念与Executors类的应用
 * 创建固定大小的线程池
 * 创建缓存线程池
 * 创建单一线程池（如何实现线程死亡后重新启动）
 * 关闭线程池 
 * shutdown与shutdownNow的比较
 * 用线程池启动定时器 
 * 调用ScheduledExecutorService的schedule方法，返回的ScheduleFuture对象可以取消任务。支持间隔重复任务的定时方式，不直接支持绝对定时方式，需要转换成相对时间方式。
 */
public class ThreadPoolTest {
    public static void main(String[] args) throws ParseException {
        //创建一个固定线程数量的线程池，内有3个线程，分配给了10个任务，3个线程执行这10个任务，
        // 当一个线程执行完一个任务之后，再去执行另一个任务，直到所有的任务执行完毕，但线程池中线程不会销毁。
        ExecutorService threadPool1 = Executors.newFixedThreadPool(3);
        //创建一个缓存线程池，缓存线程池中线程的数量是不固定的，动态变化，刚开始有3个任务，就只有3个线程，
        // 后来又来了6个任务，那就又增加了6个线程，任务执行完后，超时一段时间，多余线程销毁。
        ExecutorService threadPool2 = Executors.newCachedThreadPool();
        //创建一个只含有一个线程的线程池，该线程池只含有一个线程，当线程池里的线程被销毁后，线程池又会创建一个线程，替代原来的线程
        ExecutorService threadPool = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 10; i++) {

            final int task = i;
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    for (int j = 0; j < 10; j++) {
                        System.out.println(Thread.currentThread().getName() + "is loop of " + j + "for task of" + task);
                    }
                }
            });
        }
        //关闭线程池
        //threadPool2.shutdown();//当所有线程都空闲的时候，杀死线程，终止程序。
        //threadPool2.shutdownNow();//不管线程中的任务有没有执行完，都杀死线程。

        Executors.newScheduledThreadPool(3).schedule(
                new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("bombing!");
                    }
                }, 10, TimeUnit.SECONDS);

        //6秒后执行，每隔2秒循环执行
        Executors.newScheduledThreadPool(3).scheduleAtFixedRate(
                new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("bombing!");
                    }
                }, 6, 2, TimeUnit.SECONDS);

        //指定时间执行
        SimpleDateFormat format =  new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String timeStr="2020-06-01 20:02:00";
        Date date = format.parse(timeStr);
        //日期转时间戳（毫秒）
        long time=date.getTime();
        System.out.println("时间戳"+time);
        Executors.newScheduledThreadPool(3).scheduleAtFixedRate(
                new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("bombing!");
                    }
                }, time - System.currentTimeMillis(), 2, TimeUnit.SECONDS);
    }
}
